
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Diagnostics;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

using Swaf;
using Swaf.BizObj;
using Swaf.Gui;
using Swaf.Gui.AspNet2;
using Swaf.Security;

namespace Syrinx.Gui.AspNet
{
	public delegate void BizObjListTreeListHandler(IBizObj bizObj);
	/// <summary>
	/// this class provides an implementation of the treeview display for a given bizObjlist.
	/// </summary>
	[ToolboxData("<{0}:BizObjListTreeDisplay runat=server><{/0}:BizObjListTreeDisplay")]
	public class BizObjListTreeDisplay : TreeView, Swaf.Gui.IBizObjListDisplay
	{
		protected IBizObjList m_objectList;
		protected IBizObj m_selectedObj;
		protected TreeNode m_treeNode;
		
		protected string m_rootName = "Root";
		protected string m_name = "name";
		protected string m_fullPath = "/";
		protected string m_parentId = "parentId";

        protected int m_maxElements = 0;

		protected string m_parentIds;
		protected BizProcWidgetType m_procWidgetType = BizProcWidgetType.list;
		public string ParentBizProcIds { get { return m_parentIds; } set { m_parentIds = value; } }
		public BizProcWidgetType BizProcWidgetType { get { return m_procWidgetType; } set { m_procWidgetType = value; } }

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			this.SelectedNodeChanged += new EventHandler(BizObjListTreeDisplay_SelectedNodeChanged);
		}

		void BizObjListTreeDisplay_SelectedNodeChanged(object sender, EventArgs e)
		{
            if (this.SelectedNode.Text != m_rootName && BizObjSelected != null)
			{
				m_treeNode = this.SelectedNode;
                BizObjSelected(this, SelectedBizObj, "");
			}
		}

        #region IBizObjListDisplay Members

        public void showBizObjs(IBizObjCursor list)
        {
            m_objectList = list.Source;
			if (!Page.IsPostBack)
			{
				this.Nodes.Clear();
				for(;!list.eof;list.moveNext())
					populateTree(list.currentElement);

				if (this.Nodes.Count > 0)
					this.Nodes[0].Selected = true;
			}
        }

        public IBizObj SelectedBizObj
        {
			get
			{
				return (this.SelectedValue.Length > 0 && m_objectList !=null)
				  ? m_objectList.search("id", new Swaf.BGuid.Guid(this.SelectedValue))
				  : null;
			}		
            set
            {
                //TODO: Implement this method
            }
        }

		//ricky@syrinx.ph 8/9/07. Added support for keyvalue
        public object SelectedBizObjKeyValue 
		{ 
			get {
				if (SelectedBizObj != null)
					return SelectedBizObj.KeyValue;
				return SelectedValue; 
			}
			set { } 
		}

        public void getSelectedBizObjs(IBizObjList selected)
        {
        }
		public void setSelectedBizObjs(IBizObjList selected)
		{
		}

		public void showBizObj(IBizObj bizObj)
		{
			bizObj.put(m_fullPath, getFullPath());
			updateTreeNode(bizObj, this.Nodes);
		}

		public void addBizObj(IBizObj bizObj)
		{
			TreeNode n = new TreeNode();
			n.Value = bizObj.get("id").ToString();
			n.Text = (string)bizObj.get(m_name);

			if (bizObj.get(m_parentId) != null)
				this.SelectedNode.ChildNodes.Add(n);
			else
				this.Nodes.Add(n);
			n.Selected = true;
		}
		/// <summary>
		/// remove a bizObj from the tree list
		/// </summary>
		/// <param name="bizObj"></param>
		public void removeBizObj(IBizObj bizObj)
		{
			if (this.SelectedBizObj.get("id") == bizObj.get("id"))
				this.Nodes.Remove(this.SelectedNode);
		}

		public virtual void updateBizObjs()
		{
			//Intentionally left blank. This class is read only.
		}
		public virtual void refresh()
		{
		}


        public event Swaf.Gui.BizObjSelectedInfo BizObjSelected;
		public event Swaf.Gui.BizObjChanged BizObjUpdated;

		public event Swaf.Gui.BizObjChanged BizObjDeleted;

		public event Swaf.Gui.BizObjChanged BizObjAdded;
		public string WidgetId { get { return UniqueID; } }
        #endregion


		protected void populateTree(IBizObj bo)
		{
			TreeNode node = null;
			TreeNodeCollection parent = this.Nodes;

			if (bo.isNew != true)
			{
				if (bo.get(m_parentId) == null || (bo.get("id").Equals(bo.get(m_parentId)) && bo.get("parentHostId").Equals(bo.get(m_parentId))))
					addChildNode(bo, null);
				else
				{
					if ((node = findParentNode(bo.get(m_parentId).ToString(), parent)) == null)
						populateTree(m_objectList.search("id", bo.get(m_parentId)));
					if (node == null)
						node = findParentNode(bo.get(m_parentId).ToString(), parent);

					Debug.Assert(node != null);
					addChildNode(bo, node);
				}
			}

		}

		protected TreeNode findParentNode(string parentId, TreeNodeCollection nodes)
		{
			TreeNode node = null;
			foreach (TreeNode n in nodes)
			{
				if (n.Value != parentId)
				{
					node = findParentNode(parentId, n.ChildNodes);
					if (node != null)
						break;
				}
				else
				{
					node = n;
					break;
				}

			}
			return node;
		}

		protected void addChildNode(IBizObj bo, TreeNode parentNode)
		{
			TreeNode childNode = new TreeNode();
			childNode.Value = bo.get("id").ToString();
			childNode.Text = bo.get(m_name).ToString();
			if (parentNode == null)
				this.Nodes.Add(childNode);
			else
				parentNode.ChildNodes.Add(childNode);
			bo.isNew = true;
			childNode.Selected = true;
		}

		protected void updateTreeNode(IBizObj bo, TreeNodeCollection nodes)
		{
			foreach (TreeNode n in nodes)
				if (n.Value == bo.get("id").ToString())
				{
					n.Text = bo.get(m_name).ToString();
					break;
				}
				else
					updateTreeNode(bo, n.ChildNodes);
		}

		protected string getFullPath()
		{
			string[] root = this.SelectedNode.ValuePath.Split('/');
			string path = "/";
			foreach (string s in root)
				path += ((IBizObj)m_objectList.search("id", new Swaf.BGuid.Guid(s))).get(m_name).ToString() + "/";

			return path.Substring(0, path.Length - 1);
		}

		/// <summary>
		/// returns the selected node of the tree
		/// </summary>
		public TreeNode GetTreeNode
		{
			get { return this.SelectedNode; }
		}

		/// <summary>
		/// this method needs to be called and passed in with correct params
		/// for the class to work properly
		/// </summary>
		/// <param name="fldName">this is the field name that will be shown in the tree text</param>
		/// <param name="fullPathFldName">this is the field name that will contain the bizobj full path to it root</param>
		/// <param name="parentIdFldName">this is the field name for the parent id that is related to a given bizObj</param>
		public void setupBaseData(string fldName, string fullPathFldName, string parentIdFldName)
		{
			m_name = fldName;
			m_fullPath = fullPathFldName;
			m_parentId = parentIdFldName;
		}

        public Privileges EditPrivilege
        {
            get
            {
                return Privileges.ReadOnly;
            }
            set
            { }
        }
        public string MaxElements { get { return m_maxElements.ToString(); } set { m_maxElements = int.Parse(value); } }

	}
}
